package cn.wizzer.app.web.commons.doc;

import cn.wizzer.app.bus.modules.models.equipment.BusEquipmentReportItem;
import com.alibaba.druid.sql.visitor.functions.Char;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.EscherGraphics2d;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.usermodel.Bookmark;
import org.apache.poi.hwpf.usermodel.Bookmarks;
import org.apache.poi.hwpf.usermodel.Range;
import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackagePartName;
import org.apache.poi.openxml4j.opc.PackagingURIHelper;
import org.apache.poi.util.Units;
import org.apache.poi.wp.usermodel.HeaderFooterType;
import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.shiro.util.CollectionUtils;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;
import org.nutz.lang.util.NutMap;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;

import javax.xml.namespace.QName;
import java.awt.*;
import java.awt.font.TextAttribute;
import java.io.*;
import java.math.BigInteger;
import java.text.AttributedString;
import java.text.Normalizer;
import java.util.*;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static org.apache.poi.ooxml.POIXMLTypeLoader.DEFAULT_XML_OPTIONS;


public class DocUtils {

    private static void headers2(XWPFDocument mergedDoc, XWPFDocument doc3, boolean isOne, Map<String, String> map,int x) throws Exception {
        XWPFParagraph xwpfParagraph2 = mergedDoc.createParagraph();
        CTPPr pPr2 = xwpfParagraph2.getCTP().getPPr();
        if (pPr2 == null) {
            pPr2 = xwpfParagraph2.getCTP().addNewPPr();
        }
        CTSectPr sectPr2 = pPr2.getSectPr();
        if (sectPr2 == null) {
            sectPr2 = pPr2.addNewSectPr(); //分节符
        }
        //设置为A4
        CTPageSz sz = sectPr2.getPgSz();
        if (sz == null) {
            sz = sectPr2.addNewPgSz();
        }
        CTPageSz sz2 = mergedDoc.getDocument().getBody().getSectPr().getPgSz();
        sz.setH(sz2.getH());
        sz.setW(sz2.getW());
        // 设置上下页边距为2.54厘米
        CTPageMar pageMar = sectPr2.getPgMar();
        if (pageMar == null) {
            pageMar = sectPr2.addNewPgMar();
        }
        CTPageMar pgm= mergedDoc.getDocument().getBody().getSectPr().getPgMar();
        pageMar.setTop(pgm.getTop()); // 2.54厘米对应的twips单位
        pageMar.setBottom(pgm.getBottom()); // 2.54厘米对应的twips单位
        // 设置左右页边距为1.91厘米
        pageMar.setLeft(pgm.getLeft()); // 1.91厘米对应的twips单位
        pageMar.setRight(pgm.getRight()); // 1.91厘米对应的twips单位
        pageMar.setHeader(pgm.getHeader());
        pageMar.setFooter(pgm.getFooter());

        List<XWPFHeader> headerList2 = doc3.getHeaderList();


        List<XWPFParagraph> fzFooterParagraphs = new ArrayList<>();

        // 只需要拿一次
        if (CollectionUtils.isEmpty(fzFooterParagraphs)) {
            List<XWPFFooter> footerList = doc3.getFooterList();
            for (XWPFFooter xwpfFooter : footerList) {
                String text = xwpfFooter.getText();
                if (StringUtils.isNotBlank(text.trim())) {
                    fzFooterParagraphs = xwpfFooter.getParagraphs();
                    break;
                }
            }
        }

        if (isOne) {
            NewDocU.clearSectPr(mergedDoc);
            sectPr2.addNewPgNumType().setStart(new BigInteger("1"));
        }
        XWPFRelation relation = XWPFRelation.HEADER;
        int relationIndex = 1;
        List<POIXMLDocumentPart.RelationPart> listRelationPart = mergedDoc.getRelationParts();
        for (POIXMLDocumentPart.RelationPart rp : listRelationPart) {
            if (rp.getRelationship().getRelationshipType().equals(relation.getRelation())) {
                relationIndex++;
            }
        }
        XWPFHeader header = (XWPFHeader) mergedDoc.createRelationship(relation, XWPFFactory.getInstance(), relationIndex);


        for (XWPFHeader head : headerList2) {
            String text = head.getText();
            if (StringUtils.isNotBlank(text.trim())) {
                String xml = head._getHdrFtr().xmlText();
                //开始
                //填充图片
                List<XWPFPictureData> allPictures = head.getAllPictures();
                // 记录图片合并前及合并后的ID
                for (XWPFPictureData picture : allPictures) {
                    //String before = append.getPackageRelationship().getId();
                    String before = head.getRelationId(picture);
                    //将原文档中的图片加入到目标文档中
                    if(xml.indexOf(before)!=-1) {
                        String after = header.addPictureData(picture.getData(), Document.PICTURE_TYPE_PNG);
                        xml = xml.replace(before, after);
                    }
                }
                //原文档填充样式
                CTStyles docStyles = head.getXWPFDocument().getStyle();
                List<CTStyle> listStyle = docStyles.getStyleList();
                XWPFStyles documentStyles = mergedDoc.createStyles();
                for (int m = 0; m < listStyle.size(); m++) {
                    CTStyle style = listStyle.get(m);
                    CTString name =CTString.Factory.newInstance();
                    name.setVal("HO"+style.getName().getVal()+x);
                    style.setName(name);
                    //填充表格样式
                    XWPFStyle newStyle = new XWPFStyle(style);
                    documentStyles.addStyle(newStyle);
                    //String styleId = mergedDoc.getRelationId(documentStyles);
                    //填充表格样式
                    xml = xml.replaceAll("w:tblStyle w:val=\"" + style.getStyleId() + "\"", "w:tblStyle w:val=\"" + newStyle.getStyleId() + "\"");
                    xml = xml.replaceAll("w:pStyle w:val=\"" + style.getStyleId() + "\"", "w:pStyle w:val=\"" + newStyle.getStyleId() + "\"");
                }

                CTHdrFtr hdr = CTHdrFtr.Factory.parse(xml);
                header.setHeaderFooter(hdr);
                //header.setHeaderFooter(xwpfHeader._getHdrFtr());
            }
        }
        String relationId = mergedDoc.getRelationId(header);
        CTHdrFtrRef ctHdrFtrRef = sectPr2.addNewHeaderReference();
        ctHdrFtrRef.setId(relationId);


        XWPFRelation relation2 = XWPFRelation.FOOTER;
        int relationIndex2 = 1;
        for (POIXMLDocumentPart.RelationPart rp : mergedDoc.getRelationParts()) {
            if (rp.getRelationship().getRelationshipType().equals(relation2.getRelation())) {
                relationIndex2++;
            }
        }
        XWPFFooter footer = (XWPFFooter) mergedDoc.createRelationship(relation2, XWPFFactory.getInstance(), relationIndex2);
        for (XWPFParagraph xwpfParagraph : fzFooterParagraphs) {
            CTP ctp = footer.createParagraph().getCTP();
            ctp.set(xwpfParagraph.getCTP().copy());
        }
        // 把上面创建的footer的关联id,设到需要的分页节上CTSectPr
        String relationId2 = mergedDoc.getRelationId(footer);
        CTHdrFtrRef ctHdrFtrRef2 = sectPr2.addNewFooterReference();
        ctHdrFtrRef2.setId(relationId2);
    }

    public static XWPFDocument mergeWord2(XWPFDocument document1, List<String> docs, Map<String, String> map) throws Exception {
        //获取批注
        MyXWPFCommentsDocument myXWPFCommentsDocument = createCommentsDocument(document1);
        CTComments comments = myXWPFCommentsDocument.getComments();
        headers2(document1, document1, true,map,0);
        for (int x = 0; x < docs.size(); x++) {
            //XWPFDocument doc = new XWPFDocument(POIXMLDocument.openPackage(docs.get(x)));

            FileInputStream fis1 = new FileInputStream(docs.get(x));
            XWPFDocument doc = new XWPFDocument(fis1);
            fis1.close();
            //这里注释掉的原因是，附页内容中不会存在书签，并且处理页眉段落书签时，会与下文冲突
            //处理文档书签
            BookMarks bookMarks = new BookMarks(doc);
            // 循环进行替换
            Iterator<String> bookMarkIter = bookMarks.getNameIterator();
            while (bookMarkIter.hasNext()) {
                String bookMarkName = bookMarkIter.next();
                // 得到标签名称
                BookMark bookMark = bookMarks.getBookmark(bookMarkName);
                // 进行替换
                if (map.get(bookMarkName) != null) {
                    bookMark.insertTextAtBookMark(map.get(bookMarkName), BookMark.REPLACE);
                }
            }
            List<IBodyElement> bodyElements = doc.getBodyElements();
            for (int a = 0; a < bodyElements.size(); a++) {
                IBodyElement element = bodyElements.get(a);
                if (element.getElementType() == BodyElementType.PARAGRAPH) {
                    XWPFParagraph para = (XWPFParagraph) element;
                    XWPFParagraph newPara = document1.createParagraph();
                    // 处理分节符
                    if (para.getCTP().getPPr() != null && para.getCTP().getPPr().getSectPr() != null) {
                        // 处理分节符
                        newPara.getCTP().addNewPPr().addNewSectPr();
                        //System.out.println("这是一个分节符");
                    } else {
                        String xml = para.getCTP().xmlText();
                        //开始
                        //填充图片
                        List<XWPFPictureData> allPictures = para.getDocument().getAllPictures();
                        // 记录图片合并前及合并后的ID
                        for (XWPFPictureData picture : allPictures) {
                            //String before = append.getPackageRelationship().getId();
                            String before = doc.getRelationId(picture);
                            if(xml.indexOf(before)!=-1) {
                                //将原文档中的图片加入到目标文档中
                                String after = newPara.getDocument().addPictureData(picture.getData(), Document.PICTURE_TYPE_PNG);
                                xml = xml.replace(before, after);
                            }
                        }

                        //填充批注
                        XWPFComment[] com = para.getDocument().getComments();
                        if(com!=null) {
                            for (XWPFComment c : com) {
                                // 创建绑定ID
                                BigInteger cId = BigInteger.valueOf(Integer.valueOf(c.getId()));
                                for (XWPFComment dc : document1.getComments()) {
                                    if (dc.getId().equals(c.getId())) ;
                                    cId = cId.add(BigInteger.valueOf(1));
                                }
                                // 创建批注对象
                                CTComment ctComment = comments.addNewComment();
                                ctComment.setAuthor(c.getAuthor());
                                ctComment.addNewP().addNewR().addNewT().setStringValue(c.getText());
                                ctComment.setId(cId);
                                xml = xml.replace(c.getId(), cId.toString());
                            }
                        }

                        //原文档填充样式
                        CTStyles docStyles = para.getDocument().getStyle();
                        List<CTStyle> listStyle = docStyles.getStyleList();
                        XWPFStyles documentStyles = newPara.getDocument().createStyles();
                        for (int m = 0; m < listStyle.size(); m++) {
                            CTStyle style = listStyle.get(m);
                            CTString name =CTString.Factory.newInstance();
                            name.setVal("P"+style.getName().getVal()+(x+1));
                            style.setName(name);
                            XWPFStyle newStyle = new XWPFStyle(style);
                            documentStyles.addStyle(newStyle);
                            //String styleId = document1.getRelationId(documentStyles);
                            //填充表格样式
                            xml = xml.replaceAll("w:tblStyle w:val=\"" + style.getStyleId() + "\"", "w:tblStyle w:val=\"" + newStyle.getStyleId() + "\"");
                            xml = xml.replaceAll("w:pStyle w:val=\"" + style.getStyleId() + "\"", "w:pStyle w:val=\"" + newStyle.getStyleId() + "\"");

                        }
                        // xml = xmlto(xml);
                        CTP cptstr = CTP.Factory.parse(xml);
                        newPara.getCTP().set(cptstr);
                    }
                } else if (element.getElementType() == BodyElementType.TABLE) {
                    XWPFTable table = (XWPFTable) element;
                    XWPFTable newTable = document1.createTable();
                    String xml = table.getCTTbl().xmlText();
                    //开始
                    //填充图片
                    List<XWPFPictureData> allPictures = table.getBody().getXWPFDocument().getAllPictures();
                    // 记录图片合并前及合并后的ID
                    for (XWPFPictureData picture : allPictures) {
                        String before = doc.getRelationId(picture);
                        //将原文档中的图片加入到目标文档中
                        if(xml.indexOf(before)!=-1) {
                            String after = newTable.getBody().getXWPFDocument().addPictureData(picture.getData(), Document.PICTURE_TYPE_PNG);
                            xml = xml.replace(before, after);
                        }
                    }
                    //填充批注
                    XWPFComment[] com = table.getBody().getXWPFDocument().getComments();
                    if(com!=null) {
                        for (XWPFComment c : com) {
                            // 创建绑定ID
                            BigInteger cId = BigInteger.valueOf(Integer.valueOf(c.getId()));
                            for (XWPFComment dc : document1.getComments()) {
                                if (dc.getId().equals(c.getId())) ;
                                cId = cId.add(BigInteger.valueOf(1));
                            }
                            // 创建批注对象
                            CTComment ctComment = comments.addNewComment();
                            ctComment.setAuthor(c.getAuthor());
                            ctComment.addNewP().addNewR().addNewT().setStringValue(c.getText());
                            ctComment.setId(cId);
                            xml = xml.replace(c.getId(), cId.toString());
                        }
                    }

                    //原文档填充样式
                    CTStyles docStyles = table.getBody().getXWPFDocument().getStyle();
                    List<CTStyle> listStyle = docStyles.getStyleList();
                    XWPFStyles documentStyles = newTable.getBody().getXWPFDocument().createStyles();
                    for (int m = 0; m < listStyle.size(); m++) {
                        CTStyle style = listStyle.get(m);
                        CTString name =CTString.Factory.newInstance();
                        name.setVal("T"+style.getName().getVal()+(x+1));
                        style.setName(name);
                        //填充表格样式
                        XWPFStyle newStyle = new XWPFStyle(style);
                        documentStyles.addStyle(newStyle);
                        //String styleId = document1.getRelationId(documentStyles);
                        //填充表格样式
                        xml = xml.replaceAll("w:tblStyle w:val=\"" + style.getStyleId() + "\"", "w:tblStyle w:val=\"" + newStyle.getStyleId() + "\"");
                        xml = xml.replaceAll("w:pStyle w:val=\"" + style.getStyleId() + "\"", "w:pStyle w:val=\"" + newStyle.getStyleId() + "\"");
                    }
                    // xml = xmlto(xml);
                    CTTbl cptstr = CTTbl.Factory.parse(xml);
                    newTable.getCTTbl().set(cptstr);
                }
            }
            if (x == docs.size() - 1) {
                //如果是最后一个word则不需要设置“分节符”，直接给本段设置页眉即可
                CTSectPr sectPr2 = document1.getDocument().getBody().addNewSectPr();
                //设置为A4
                CTPageSz sz = sectPr2.getPgSz();
                if (sz == null) {
                    sz = sectPr2.addNewPgSz();
                }
                CTPageSz sz2 = doc.getDocument().getBody().getSectPr().getPgSz();
                sz.setH(sz2.getH());
                sz.setW(sz2.getW());
                // 设置上下页边距为2.54厘米
                CTPageMar pageMar = sectPr2.getPgMar();
                if (pageMar == null) {
                    pageMar = sectPr2.addNewPgMar();
                }
                CTPageMar pgm= doc.getDocument().getBody().getSectPr().getPgMar();
                pageMar.setTop(pgm.getTop()); // 2.54厘米对应的twips单位
                pageMar.setBottom(pgm.getBottom()); // 2.54厘米对应的twips单位
                // 设置左右页边距为1.91厘米
                pageMar.setLeft(pgm.getLeft()); // 1.91厘米对应的twips单位
                pageMar.setRight(pgm.getRight()); // 1.91厘米对应的twips单位
                pageMar.setHeader(pgm.getHeader());
                pageMar.setFooter(pgm.getFooter());

                XWPFHeaderFooterPolicy headerFooterPolicy2 = new XWPFHeaderFooterPolicy(document1, sectPr2);
                XWPFHeader header2 = headerFooterPolicy2.createHeader(XWPFHeaderFooterPolicy.DEFAULT, new XWPFParagraph[]{});
                List<XWPFHeader> headlist = doc.getHeaderList();
                for (XWPFHeader head : headlist) {
                    //处理页眉中的书签
                    /*for (XWPFParagraph p :head.getParagraphs()){
                        List<CTBookmark> books =  p.getCTP().getBookmarkStartList();
                        for(CTBookmark book:books){
                            if (map.get(book.getName()) != null) {
                                p.createRun().setText(map.get(book.getName()));
                            }
                        }
                    }
                    for (XWPFTable t :head.getTables()){
                        for (XWPFTableRow row : t.getRows()){
                            for (XWPFTableCell cell : row.getTableCells()){
                                for ( XWPFParagraph p :cell.getParagraphs()){
                                    List<CTBookmark> books =  p.getCTP().getBookmarkStartList();
                                    for(CTBookmark book:books){
                                        if (map.get(book.getName()) != null) {
                                            p.createRun().setText(map.get(book.getName()));
                                        }
                                    }
                                }
                            }
                        }
                    }*/
                    if (StringUtils.isNotBlank(head.getText().trim())) {
                        String xml = head._getHdrFtr().xmlText();
                        //开始
                        //填充图片
                        List<XWPFPictureData> allPictures = head.getAllPictures();
                        // 记录图片合并前及合并后的ID
                        for (XWPFPictureData picture : allPictures) {
                            String before = head.getRelationId(picture);
                            //将原文档中的图片加入到目标文档中
                            if(xml.indexOf(before)!=-1) {
                                String after = header2.addPictureData(picture.getData(), Document.PICTURE_TYPE_PNG);
                                xml = xml.replace(before, after);
                            }
                        }
                        //原文档填充样式
                        CTStyles docStyles = head.getXWPFDocument().getStyle();
                        List<CTStyle> listStyle = docStyles.getStyleList();
                        XWPFStyles documentStyles = document1.createStyles();
                        for (int m = 0; m < listStyle.size(); m++) {
                            CTStyle style = listStyle.get(m);
                            CTString name =CTString.Factory.newInstance();
                            name.setVal("HF"+style.getName().getVal()+(x+1));
                            style.setName(name);
                            //填充表格样式
                            XWPFStyle newStyle = new XWPFStyle(style);
                            documentStyles.addStyle(newStyle);
                            //String styleId = document1.getRelationId(documentStyles);
                            //填充表格样式
                            xml = xml.replaceAll("w:tblStyle w:val=\"" + style.getStyleId() + "\"", "w:tblStyle w:val=\"" + newStyle.getStyleId() + "\"");
                            xml = xml.replaceAll("w:pStyle w:val=\"" + style.getStyleId() + "\"", "w:pStyle w:val=\"" + newStyle.getStyleId() + "\"");
                        }
                        CTHdrFtr hdr = CTHdrFtr.Factory.parse(xml);
                        header2.setHeaderFooter(hdr);

                    }
                }
                String relationId = document1.getRelationId(header2);
                CTHdrFtrRef ctHdrFtrRef = sectPr2.addNewHeaderReference();
                ctHdrFtrRef.setId(relationId);



                List<XWPFParagraph> fzFooterParagraphs = new ArrayList<>();
                // 只需要拿一次
                if (CollectionUtils.isEmpty(fzFooterParagraphs)) {
                    List<XWPFFooter> footerList = doc.getFooterList();
                    for (XWPFFooter xwpfFooter : footerList) {
                        String text = xwpfFooter.getText();
                        if (StringUtils.isNotBlank(text.trim())) {
                            fzFooterParagraphs = xwpfFooter.getParagraphs();
                            break;
                        }
                    }
                }
                /*XWPFRelation relation2 = XWPFRelation.FOOTER;
                int relationIndex2 = 1;
                for (POIXMLDocumentPart.RelationPart rp : document1.getRelationParts()) {
                    if (rp.getRelationship().getRelationshipType().equals(relation2.getRelation())) {
                        relationIndex2++;
                    }
                }*/
                //XWPFFooter footer = (XWPFFooter) document1.createRelationship(relation2, XWPFFactory.getInstance(), relationIndex2);

                XWPFFooter footer = headerFooterPolicy2.createFooter(XWPFHeaderFooterPolicy.DEFAULT, new XWPFParagraph[]{});
                for (XWPFParagraph xwpfParagraph : fzFooterParagraphs) {
                    CTP ctp = footer.createParagraph().getCTP();
                    ctp.set(xwpfParagraph.getCTP().copy());
                }
                // 把上面创建的footer的关联id,设到需要的分页节上CTSectPr
                String relationId2 = document1.getRelationId(footer);
                CTHdrFtrRef ctHdrFtrRef2 = sectPr2.addNewFooterReference();
                ctHdrFtrRef2.setId(relationId2);
            } else {
                headers2(document1, doc, false,map,x);
            }
            doc.close();
        }
        return document1;
    }

    private static String xmlto(String docXml){
        String startChar = "<mc:Fallback>";//文档解析错误 的内容标签
        String endChar = "</mc:Fallback>";
        // 获取开始字符的索引
        int startIndex = docXml.indexOf(startChar);
        // 获取结束字符的索引
        int endIndex = docXml.indexOf(endChar, startIndex + 1);

        // 如果字符未找到，则返回原始字符串或抛出异常
        if (startIndex != -1 && endIndex != -1) {
            // 截取从开始字符到结束字符之间的内容，并移除
            docXml = docXml.substring(0, startIndex) + docXml.substring(endIndex + endChar.length());
        }
        return docXml;
    }

    public static void FileToFile2(String destFile, String destFile2, Map<String, String> map, List<String> docs) throws Exception {
        ByteArrayOutputStream ostream = new ByteArrayOutputStream();
        //2007格式模版
        if (destFile.toLowerCase().endsWith(".docx")) {
            FileInputStream fis = new FileInputStream(destFile);
            XWPFDocument document = new XWPFDocument(fis);
            fis.close();
           // XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(destFile));
            BookMarks bookMarks = new BookMarks(document);
            // 循环进行替换
            Iterator<String> bookMarkIter = bookMarks.getNameIterator();
            while (bookMarkIter.hasNext()) {
                String bookMarkName = bookMarkIter.next();
                // 得到标签名称
                BookMark bookMark = bookMarks.getBookmark(bookMarkName);
                // 进行替换
                if (map.get(bookMarkName) != null) {
                    bookMark.insertTextAtBookMark(map.get(bookMarkName), BookMark.REPLACE);
                }
            }
            //合并文件
            if (docs != null && docs.size() > 0) {
                mergeWord2(document, docs,map);
                //document = NewDocU.mergeDoc(document,docs);
            }
            document.write(ostream);
            document.close();

            /*PdfOptions pdfOptions = PdfOptions.create();
            FileOutputStream fileOutputStream = new FileOutputStream(new File(destFile.replace(".docx", ".pdf")));
            try {
                PdfConverter.getInstance().convert(document,fileOutputStream,pdfOptions);
            }catch (Exception e){
                e.printStackTrace();
            }
            fileOutputStream.close();*/
        }
        //2003格式模版
        else {
            HWPFDocument doc = new HWPFDocument(new FileInputStream(new File(destFile)));
            Bookmarks bookmarks = doc.getBookmarks();
            int count = bookmarks.getBookmarksCount();
//				System.out.println(" Size: " + bookmarks.getBookmarksCount());
            for (int i = 0; i < count; i++) {
                final Bookmark bookmark = doc.getBookmarks().getBookmark(i);
                if (bookmark.getName() != null && !bookmark.getName().startsWith("_")) {
//						System.out.println(i + " | " + bookmark.getName());
                    final String pValue = map.get(bookmark.getName());
                    final Range range = new Range(bookmark.getStart(), bookmark.getEnd(), doc);
                    /*System.out.println(range.text());*/
                    if (range.text().length() > 0) {
                        range.replaceText(pValue, false);
                    } else {
                        range.insertBefore(pValue);
                    }
                }
            }
            doc.write(ostream);
        }
        // 输出word文件
        File file = new File(destFile2);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        OutputStream outs = new FileOutputStream(destFile2);
        outs.write(ostream.toByteArray());
        ostream.close();
        outs.close();
    }

    //两个对象进行追加
    public static XWPFDocument mergeWord(XWPFDocument document1, List<String> docs) throws Exception {
        //headers2(document1, document1, false);
        //获取批注
        MyXWPFCommentsDocument myXWPFCommentsDocument = createCommentsDocument(document1);
        CTComments comments = myXWPFCommentsDocument.getComments();
        for (int i = 0; i < docs.size(); i++) {
            String name = docs.get(i).substring(docs.get(i).lastIndexOf("/") + 1, docs.get(i).indexOf("."));
            //XWPFDocument doc = new XWPFDocument(POIXMLDocument.openPackage(docs.get(i)));
            FileInputStream fis = new FileInputStream(docs.get(i));
            XWPFDocument doc = new XWPFDocument(fis);
            fis.close();
            //截取文档2
            CTBody src2Body = doc.getDocument().getBody();
            XmlOptions optionsOuter = new XmlOptions();
            optionsOuter.setSaveOuter();
            String appendString = src2Body.xmlText(optionsOuter);
            String addprefix = appendString.substring(1, appendString.indexOf(">"));
            String addPart = (appendString.substring(appendString.indexOf(">") + 1, appendString.lastIndexOf("<")));

            //设置分页符
            XWPFParagraph paragraph = document1.createParagraph();
            paragraph.setPageBreak(true);
            //paragraph.getCTP().addNewPPr().addNewSectPr();

            CTBody src1Body = document1.getDocument().getBody();
            String srcString = src1Body.xmlText();

            String prefix = srcString.substring(0, srcString.indexOf(">") + 1);

            //填充头部协议
            String[] strs = addprefix.split(" ");
            String newprefix = " ";
            for (int j = 1; j < strs.length; j++) {
                String str = strs[j];
                if (!prefix.contains(str)) {
                    newprefix += str + " ";
                }
            }
            prefix = prefix.substring(0, prefix.length() - 1) + newprefix + prefix.substring(prefix.length() - 1, prefix.length());

            //截取文档1
            String mainPart = srcString.substring(srcString.indexOf(">") + 1, srcString.lastIndexOf("<"));
            String sufix = srcString.substring(srcString.lastIndexOf("<"));


            //填充图片
            List<XWPFPictureData> allPictures = doc.getAllPictures();
            // 记录图片合并前及合并后的ID
            for (XWPFPictureData picture : allPictures) {
                //String before = append.getPackageRelationship().getId();
                String before = doc.getRelationId(picture);
                //将原文档中的图片加入到目标文档中
                String after = document1.addPictureData(picture.getData(), Document.PICTURE_TYPE_PNG);
                addPart = addPart.replace(before, after);
            }

            //填充批注
            XWPFComment[] com = doc.getComments();
            if(com!=null) {
                for (XWPFComment c : com) {
                    // 创建绑定ID
                    BigInteger cId = BigInteger.valueOf(Integer.valueOf(c.getId()));
                    for (XWPFComment dc : document1.getComments()) {
                        if (dc.getId().equals(c.getId())) ;
                        cId = cId.add(BigInteger.valueOf(1));
                    }
                    // 创建批注对象
                    CTComment ctComment = comments.addNewComment();
                    ctComment.setAuthor(c.getAuthor());
                    //ctComment.setInitials("AR");
                    //ctComment.setDate(new GregorianCalendar(Locale.US));
                    ctComment.addNewP().addNewR().addNewT().setStringValue(c.getText());
                    ctComment.setId(cId);
                    addPart = addPart.replace(c.getId(), cId.toString());
                }
            }

            //原文档填充样式
            CTStyles docStyles = doc.getStyle();
            List<CTStyle> listStyle = docStyles.getStyleList();
            XWPFStyles documentStyles = document1.createStyles();
            for (int m = 0; m < listStyle.size(); m++) {
                CTStyle style = listStyle.get(m);
                String styleId = style.getStyleId() + name;
                //填充表格样式
                addPart = addPart.replaceAll("w:tblStyle w:val=\"" + style.getStyleId() + "\"", "w:tblStyle w:val=\"" + styleId + "\"");

                style.setStyleId(styleId);
                XWPFStyle newStyle = new XWPFStyle(style);
                documentStyles.addStyle(newStyle);
            }

            //页眉
            //如果是最后一个word则不需要设置“分节符”，直接给本段设置页眉即可
            /*XWPFHeader headdoc = null;
            for (XWPFHeader xwpfHeader : doc.getHeaderList()) {
                String text = xwpfHeader.getText();
                if (StringUtils.isNotBlank(text.trim())) {
                    headdoc = xwpfHeader;
                    break;
                }
            }
            String headerBefore = doc.getRelationId(headdoc);
            if (headdoc != null) {
                //headdoc = doc.createHeader(HeaderFooterType.DEFAULT);
                //headerBefore = doc.getRelationId(headdoc);
                //doc.getDocument().getBody().getSectPr().addNewHeaderReference().setId(headerBefore);
                XWPFRelation relation = XWPFRelation.HEADER;
                int relationIndex = 1;
                List<POIXMLDocumentPart.RelationPart> listRelationPart = document1.getRelationParts();
                for (POIXMLDocumentPart.RelationPart rp : listRelationPart) {
                    if (rp.getRelationship().getRelationshipType().equals(relation.getRelation())) {
                        relationIndex++;
                    }
                }
                //XWPFHeader header = (XWPFHeader) document1.createRelationship(relation, XWPFFactory.getInstance(), relationIndex);
                XWPFHeader header = document1.createHeader(HeaderFooterType.DEFAULT);
                header.setHeaderFooter(headdoc._getHdrFtr());
                String after = document1.getRelationId(header);
                addPart.replace(headerBefore, after);
            }*/

            CTBody makeBody = CTBody.Factory.parse(prefix + mainPart + addPart + sufix);
            src1Body.set(makeBody);
            doc.close();
            //document1.createParagraph().getCTP().addNewPPr().addNewSectPr();
        }
        return document1;
    }

    private static String headers(XWPFDocument mergedDoc, XWPFDocument doc3, boolean isHeader) {
        XWPFParagraph xwpfParagraph2 = mergedDoc.createParagraph();
        CTPPr pPr2 = xwpfParagraph2.getCTP().getPPr();
        if (pPr2 == null) {
            pPr2 = xwpfParagraph2.getCTP().addNewPPr();
        }
        CTSectPr sectPr2 = pPr2.getSectPr();
        if (sectPr2 == null) {
            sectPr2 = pPr2.addNewSectPr(); //分节符
        }
        //设置为A4
        CTPageSz sz = sectPr2.getPgSz();
        if (sz == null) {
            sz = sectPr2.addNewPgSz();
        }
        sz.setH(new BigInteger("16838"));
        sz.setW(new BigInteger("11906"));
        List<XWPFParagraph> headerParagraphs2 = new ArrayList<>();
        List<XWPFHeader> headerList2 = doc3.getHeaderList();
        String oldId = "";
        for (XWPFHeader xwpfHeader : headerList2) {
            String text = xwpfHeader.getText();
            if (StringUtils.isNotBlank(text.trim())) {
                headerParagraphs2 = xwpfHeader.getParagraphs();
                oldId = doc3.getRelationId(xwpfHeader);
                break;
            }
        }

        List<XWPFParagraph> fzFooterParagraphs = new ArrayList<>();

        // 只需要拿一次
        if (CollectionUtils.isEmpty(fzFooterParagraphs)) {
            List<XWPFFooter> footerList = doc3.getFooterList();
            for (XWPFFooter xwpfFooter : footerList) {
                String text = xwpfFooter.getText();
                if (StringUtils.isNotBlank(text.trim())) {
                    fzFooterParagraphs = xwpfFooter.getParagraphs();
                    break;
                }
            }
        }


        XWPFRelation relation = XWPFRelation.HEADER;
        int relationIndex = 1;
        List<POIXMLDocumentPart.RelationPart> listRelationPart = mergedDoc.getRelationParts();
        for (POIXMLDocumentPart.RelationPart rp : listRelationPart) {
            if (rp.getRelationship().getRelationshipType().equals(relation.getRelation())) {
                relationIndex++;
            }
        }
        XWPFHeader header = (XWPFHeader) mergedDoc.createRelationship(relation, XWPFFactory.getInstance(), relationIndex);
        for (XWPFParagraph xwpfParagraph : headerParagraphs2) {
            XWPFParagraph paragraph = header.createParagraph();
            //System.out.println("--------"+xwpfParagraph.getCTP().xmlText());
            if (xwpfParagraph.getCTP().xmlText().contains("MERGEFORMAT")) {

            } else {
                paragraph.getCTP().set(xwpfParagraph.getCTP().copy());
            }
        }
        String relationId = mergedDoc.getRelationId(header);
        CTHdrFtrRef ctHdrFtrRef = sectPr2.addNewHeaderReference();
        ctHdrFtrRef.setId(relationId);

        XWPFRelation relation2 = XWPFRelation.FOOTER;
        int relationIndex2 = 1;
        for (POIXMLDocumentPart.RelationPart rp : mergedDoc.getRelationParts()) {
            if (rp.getRelationship().getRelationshipType().equals(relation2.getRelation())) {
                relationIndex2++;
            }
        }
        XWPFFooter footer = (XWPFFooter) mergedDoc.createRelationship(relation2, XWPFFactory.getInstance(), relationIndex2);
        for (XWPFParagraph xwpfParagraph : fzFooterParagraphs) {
            CTP ctp = footer.createParagraph().getCTP();
            ctp.set(xwpfParagraph.getCTP().copy());
        }
        // 把上面创建的footer的关联id,设到需要的分页节上CTSectPr
        String relationId2 = mergedDoc.getRelationId(footer);
        CTHdrFtrRef ctHdrFtrRef2 = sectPr2.addNewFooterReference();
        ctHdrFtrRef2.setId(relationId2);

        return oldId + "," + relationId;
    }


    //第一个核心方法获取自己创建得自定义得对象
    private static MyXWPFCommentsDocument createCommentsDocument(XWPFDocument document) throws Exception {
        OPCPackage oPCPackage = document.getPackage();
        PackagePartName partName = PackagingURIHelper.createPartName("/word/comments.xml");
        PackagePart part = oPCPackage.createPart(partName, "application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml");


        MyXWPFCommentsDocument myXWPFCommentsDocument = new MyXWPFCommentsDocument(part);

        String rId = "rId" + (document.getRelationParts().size() + 1);
        document.addRelation(rId, XWPFRelation.COMMENT, myXWPFCommentsDocument);

        return myXWPFCommentsDocument;
    }

    //第二个就是自己定义得核心对象
    private static class MyXWPFCommentsDocument extends POIXMLDocumentPart {

        private CTComments comments;

        private MyXWPFCommentsDocument(PackagePart part) throws Exception {
            super(part);
            comments = CommentsDocument.Factory.newInstance().addNewComments();
        }

        private CTComments getComments() {
            return comments;
        }

        @Override
        protected void commit() throws IOException {
            XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
            xmlOptions.setSaveSyntheticDocumentElement(new QName(CTComments.type.getName().getNamespaceURI(), "comments"));
            PackagePart part = getPackagePart();
            OutputStream out = part.getOutputStream();
            comments.save(out, xmlOptions);
            out.close();
        }

    }


    public static void FileToFileLzd(String destFile, String destFile2, List<Map<String, String>> listMap) throws Exception {
        ByteArrayOutputStream ostream = new ByteArrayOutputStream();
        //2007格式模版
        if (destFile.toLowerCase().endsWith(".docx")) {
            //XWPFDocument newDoc = new XWPFDocument(POIXMLDocument.openPackage(destFile));
            FileInputStream fis = new FileInputStream(destFile);
            XWPFDocument newDoc = new XWPFDocument(fis);
            fis.close();
            if(listMap.size()>0){
                Map<String, String> map = listMap.get(0);
                BookMarks bookMarks = new BookMarks(newDoc);
                // 循环进行替换
                Iterator<String> bookMarkIter = bookMarks.getNameIterator();
                while (bookMarkIter.hasNext()) {
                    String bookMarkName = bookMarkIter.next();
                    // 得到标签名称
                    BookMark bookMark = bookMarks.getBookmark(bookMarkName);
                    // 进行替换
                    if (map.get(bookMarkName) != null) {
                        bookMark.insertTextAtBookMark(map.get(bookMarkName), BookMark.REPLACE);
                    }
                }
                if(listMap.size()>1){
                    for (int i = 1; i < listMap.size(); i++){
                        //XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(destFile));

                        FileInputStream fis1 = new FileInputStream(destFile);
                        XWPFDocument document = new XWPFDocument(fis1);
                        fis1.close();
                        copyBody(document,newDoc,listMap.get(i));
                        document.close();
                    }
                }
            }

            newDoc.write(ostream);
            newDoc.close();
        }
        // 输出word文件
        File file = new File(destFile2);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        OutputStream outs = new FileOutputStream(destFile2);
        outs.write(ostream.toByteArray());
        ostream.close();
        outs.close();
    }


    private  static void copyBody(XWPFDocument document, XWPFDocument newDoc,Map<String, String> map) throws Exception{
        BookMarks bookMarks = new BookMarks(document);
        // 循环进行替换
        Iterator<String> bookMarkIter = bookMarks.getNameIterator();
        while (bookMarkIter.hasNext()) {
            String bookMarkName = bookMarkIter.next();
            // 得到标签名称
            BookMark bookMark = bookMarks.getBookmark(bookMarkName);
            // 进行替换
            if (map.get(bookMarkName) != null) {
                bookMark.insertTextAtBookMark(map.get(bookMarkName), BookMark.REPLACE);
            }
        }
        List<IBodyElement> bodyElements = document.getBodyElements();
        for (int a = 0; a < bodyElements.size(); a++) {
            IBodyElement element = bodyElements.get(a);
            if (element.getElementType() == BodyElementType.PARAGRAPH) {
                XWPFParagraph para = (XWPFParagraph) element;
                XWPFParagraph newPara = newDoc.createParagraph();
                // 处理分节符
                if (para.getCTP().getPPr() != null && para.getCTP().getPPr().getSectPr() != null) {
                    // 处理分节符
                    newPara.getCTP().addNewPPr().addNewSectPr();
                    //System.out.println("这是一个分节符");
                } else {
                    String xml = para.getCTP().xmlText();
                    //开始
                    //填充图片
                    List<XWPFPictureData> allPictures = para.getDocument().getAllPictures();
                    // 记录图片合并前及合并后的ID
                    for (XWPFPictureData picture : allPictures) {
                        //String before = append.getPackageRelationship().getId();
                        String before = document.getRelationId(picture);
                        //将原文档中的图片加入到目标文档中
                        String after = newPara.getDocument().addPictureData(picture.getData(), Document.PICTURE_TYPE_PNG);
                        xml = xml.replace(before, after);
                    }


                    //原文档填充样式
                    CTStyles docStyles = para.getDocument().getStyle();
                    List<CTStyle> listStyle = docStyles.getStyleList();
                    XWPFStyles documentStyles = newPara.getDocument().createStyles();
                    for (int m = 0; m < listStyle.size(); m++) {
                        CTStyle style = listStyle.get(m);
                        XWPFStyle newStyle = new XWPFStyle(style);
                        documentStyles.addStyle(newStyle);
                        String styleId = newDoc.getRelationId(documentStyles);
                        //填充表格样式
                        xml = xml.replaceAll("w:tblStyle w:val=\"" + style.getStyleId() + "\"", "w:tblStyle w:val=\"" + styleId + "\"");

                    }
                    // xml = xmlto(xml);
                    CTP cptstr = CTP.Factory.parse(xml);
                    newPara.getCTP().set(cptstr);
                }
            } else if (element.getElementType() == BodyElementType.TABLE) {
                XWPFTable table = (XWPFTable) element;
                XWPFTable newTable = newDoc.createTable();
                String xml = table.getCTTbl().xmlText();
                //开始
                //填充图片
                List<XWPFPictureData> allPictures = table.getBody().getXWPFDocument().getAllPictures();
                // 记录图片合并前及合并后的ID
                for (XWPFPictureData picture : allPictures) {
                    String before = document.getRelationId(picture);
                    //将原文档中的图片加入到目标文档中
                    String after = newTable.getBody().getXWPFDocument().addPictureData(picture.getData(), Document.PICTURE_TYPE_PNG);
                    xml = xml.replace(before, after);
                }

                //原文档填充样式
                CTStyles docStyles = table.getBody().getXWPFDocument().getStyle();
                List<CTStyle> listStyle = docStyles.getStyleList();
                XWPFStyles documentStyles = newTable.getBody().getXWPFDocument().createStyles();
                for (int m = 0; m < listStyle.size(); m++) {
                    CTStyle style = listStyle.get(m);
                    //填充表格样式
                    XWPFStyle newStyle = new XWPFStyle(style);
                    documentStyles.addStyle(newStyle);
                    String styleId = newDoc.getRelationId(documentStyles);
                    //填充表格样式
                    xml = xml.replaceAll("w:tblStyle w:val=\"" + style.getStyleId() + "\"", "w:tblStyle w:val=\"" + styleId + "\"");
                }
                // xml = xmlto(xml);
                CTTbl cptstr = CTTbl.Factory.parse(xml);
                newTable.getCTTbl().set(cptstr);
            }
        }
    }


    public static void FileToFileFy(String destFile, String destFile2, Map<String, String> map, List<String> count) throws Exception {
        ByteArrayOutputStream ostream = new ByteArrayOutputStream();
        //2007格式模版
        if (destFile.toLowerCase().endsWith(".docx")) {
            //XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(destFile));
            FileInputStream fis1 = new FileInputStream(destFile);
            XWPFDocument document = new XWPFDocument(fis1);
            fis1.close();
            if(map!=null) {
                BookMarks bookMarks = new BookMarks(document);
                // 循环进行替换
                Iterator<String> bookMarkIter = bookMarks.getNameIterator();
                while (bookMarkIter.hasNext()) {
                    String bookMarkName = bookMarkIter.next();
                    // 得到标签名称
                    BookMark bookMark = bookMarks.getBookmark(bookMarkName);
                    // 进行替换
                    if (map.get(bookMarkName) != null) {
                        bookMark.insertTextAtBookMark(map.get(bookMarkName), BookMark.REPLACE);
                    }
                }
            }
            List<XWPFTable> bodyTables = document.getTables();
            //获取第一个表格
            XWPFTable table = bodyTables.get(0);
            List<XWPFTableRow> rowList = table.getRows();
            //遍历所有的行
            List<Integer>  removeList = new ArrayList<>();
            boolean  isRemove = false;
            for (int i = 0;i<rowList.size();i++){
                XWPFTableRow row = rowList.get(i);
                //得到行中的列信息
                List<XWPFTableCell> cellList = row.getTableCells();
                if(cellList.size()>0) {
                    //得到第一个表格
                    XWPFTableCell cell = cellList.get(0);
                    if(!count.contains(cell.getText().trim())&&(cell.getText().trim()).matches("\\d+")){
                        removeList.add(i);
                        isRemove = true;
                    }else if(isRemove && (cell.getText()==null || cell.getText().trim().equals(""))){//如果没有内容我则认为它是一个合并单元格，与上一个单元格一样删除
                        removeList.add(i);
                        isRemove = true;
                    }else{
                        isRemove = false;
                    }
                    //CTHeight height = row.getCtRow().getTrPr().getTrHeightArray(0);
                    //int rowspan = (int)Math.ceil((double)height.getVal() / row.getHeight());
                    /*CTTcPr pr= cell.getCTTc().getTcPr();
                    if(pr.getGridSpan()!=null){
                        BigInteger span= pr.getGridSpan().getVal();
                        System.out.println("跨行"+span.intValue());
                    }*/
                }
            }
            for (int i =0 ;i< removeList.size();i++){
                table.removeRow(removeList.get(i)-i);
            }
            List<XWPFTableRow> newRowList = table.getRows();
            //遍历所有的行,重新排序
            int order = 1;
            for (int i = 1;i<newRowList.size();i++){
                XWPFTableRow row = newRowList.get(i);
                //得到行中的列信息
                List<XWPFTableCell> cellList = row.getTableCells();
                if(cellList.size()>0) {
                    //得到第一个表格
                    XWPFTableCell cell = cellList.get(0);
                    if((cell.getText().trim()).matches("\\d+")){//如果是数字
                        String cellXml = cell.getCTTc().xmlText();
                        cellXml = cellXml.replaceAll("<w:t>"+cell.getText().trim()+"</w:t>","<w:t>"+order+"</w:t>");
                        cell.getCTTc().set(CTTc.Factory.parse(cellXml));
                        order++;
                    }
                }
            }
            document.write(ostream);
            document.close();
        }
        // 输出word文件
        File file = new File(destFile2);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        OutputStream outs = new FileOutputStream(destFile2);
        outs.write(ostream.toByteArray());
        ostream.close();
        outs.close();
    }

    public static void FileEReport(String destFile, String destFile2, Map<String, String> map, List<BusEquipmentReportItem> reportItems) throws Exception {
        ByteArrayOutputStream ostream = new ByteArrayOutputStream();
        //2007格式模版
        if (destFile.toLowerCase().endsWith(".docx")) {
            //XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(destFile));

            FileInputStream fis1 = new FileInputStream(destFile);
            XWPFDocument document = new XWPFDocument(fis1);
            fis1.close();
            if(map!=null) {
                BookMarks bookMarks = new BookMarks(document);
                // 循环进行替换
                Iterator<String> bookMarkIter = bookMarks.getNameIterator();
                while (bookMarkIter.hasNext()) {
                    String bookMarkName = bookMarkIter.next();
                    // 得到标签名称
                    BookMark bookMark = bookMarks.getBookmark(bookMarkName);
                    // 进行替换
                    if (map.get(bookMarkName) != null) {
                        bookMark.insertTextAtBookMark(map.get(bookMarkName), BookMark.REPLACE);
                    }
                }
            }
            List<XWPFTable> bodyTables = document.getTables();
            //获取第一个表格
            if(bodyTables.size()>2){
                XWPFTable table = bodyTables.get(1);
                List<XWPFTableRow> rowList = table.getRows();
                if(rowList.size()>0){
                    XWPFTableRow row = rowList.get(0);//得第一行
                    //增加一行
                    for(BusEquipmentReportItem item:reportItems) {
                        XWPFTableRow newRow = table.createRow();
                        newRow.setHeight(row.getHeight());
                        for (int i = 0; i < row.getTableCells().size(); i++) {
                            XWPFTableCell cell = row.getCell(i);
                            XWPFTableCell newCell = newRow.getCell(i);
                            newCell.getCTTc().setTcPr(cell.getCTTc().getTcPr());
                            if (cell.getParagraphs().size() > 0) {
                                XWPFParagraph sourceParagraph = cell.getParagraphs().get(0);
                                if (sourceParagraph != null && sourceParagraph.getCTP() != null) {
                                    XWPFParagraph newParagraph = newCell.getParagraphs().get(0);
                                    newParagraph.getCTP().setPPr(sourceParagraph.getCTP().getPPr());
                                    if (sourceParagraph.getRuns().size() > 0) {
                                        XWPFRun sourceRun = sourceParagraph.getRuns().get(0);
                                        if (sourceRun != null && sourceRun.getCTR() != null) {
                                            XWPFRun newRun = newParagraph.createRun();
                                            newRun.getCTR().setRPr(sourceRun.getCTR().getRPr());
                                            if(i==0){
                                                newRun.setText(item.getName());
                                            }else if(i==1){
                                                newRun.setText(item.getRes());
                                            }else{
                                                newRun.setText(item.getIndicators());
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

            }
            document.write(ostream);
            document.close();
        }
        // 输出word文件
        File file = new File(destFile2);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        OutputStream outs = new FileOutputStream(destFile2);
        outs.write(ostream.toByteArray());
        ostream.close();
        outs.close();
    }

    public static void findSupSub(String input) {
        // 匹配上标和下标的正则表达式
        Pattern pattern = Pattern.compile("[\\u2070-\\u209F\\u00B9-\\u00B9\\u00B2-\\u00B3\\u2070-\\u209F\\u2080-\\u2089\\u1D43-\\u1D6A]");

        // 匹配所有的 Unicode 编码的上标字符，但排除下标字符
        Pattern superscriptPattern = Pattern.compile("[\\u2070-\\u2079\\u00B9\\u00B2\\u00B3\\u2074-\\u2079\\u00B9\\u207A-\\u207C\\u207D-\\u207E\\u207F\\u2120\\u1D2C-\\u1D61\\u1D78\\u2C7D\\u1D25-\\u1D2B]");

        // 匹配所有的 Unicode 编码的下标字符，但排除上标字符
       // Pattern subscriptPattern = Pattern.compile("[\\u2080-\\u2089\\u2090-\\u209C\\u1D62-\\u1D6A&&[^\\u2070-\\u2079\\u00B9-\\u00B9\\u00B2-\\u00B3\\u2074-\\u2079\\u00B9-\\u00B9\\u1D43-\\u1D6A]]");
        Pattern subscriptPattern = Pattern.compile("[\\u2080-\\u2089\\u00B0\\u208A-\\u208C\\u208D-\\u208E\\u2090-\\u209C]");

        // 查找匹配的上标
        Matcher inputPattern = pattern.matcher(input);
        int start = 0;
        List<NutMap> strs = new ArrayList<>();
        while (inputPattern.find()) {
            String in = inputPattern.group();
            if(inputPattern.start()>0){
                String str = input.substring(start,inputPattern.start());
                if(!str.equals("")) {
                    strs.add(new NutMap().addv("value", str).addv("type", 0));
                }
                if(superscriptPattern.matcher(in).matches()){
                    strs.add(new NutMap().addv("value",in).addv("type",1));
                }else if(subscriptPattern.matcher(in).matches()){
                    strs.add(new NutMap().addv("value",in).addv("type",2));
                }else{
                    strs.add(new NutMap().addv("value",in).addv("type",4));
                }
                start = inputPattern.end();
            }
        }
        if(start != input.length()-1){
            String str = input.substring(start, input.length());
            if(!str.equals("")) {
                strs.add(new NutMap().addv("value", str).addv("type", 0));
            }
        }
        for(NutMap map :strs){
           // System.out.println(map.get("value").toString()+map.get("type"));
        }
    }
    public static boolean isSuperscript(String c) {
        return Character.UnicodeBlock.of((char) c.getBytes()[0])==Character.UnicodeBlock.SUPERSCRIPTS_AND_SUBSCRIPTS;
    }
    public static void main(String[] args) {
        String text = "12345";
        System.out.println(text.substring(0,text.length()-2));
    }
}
